package cn.db101.kaoqinserver.service;

import cn.db101.kaoqinserver.domain.Check;
import cn.db101.kaoqinserver.domain.Classes;
import cn.db101.kaoqinserver.domain.Course;
import cn.db101.kaoqinserver.domain.User;
import cn.db101.kaoqinserver.enumration.CheckStatus;
import cn.db101.kaoqinserver.mapper.CheckMapper;
import cn.db101.kaoqinserver.mapper.ClassesMapper;
import cn.db101.kaoqinserver.mapper.CourseMapper;
import cn.db101.kaoqinserver.mapper.UserMapper;
import cn.db101.kaoqinserver.model.request.CourseParam;
import cn.db101.kaoqinserver.model.response.CourseResponse;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
* @author Admin
* @description 针对表【t_course(课程表)】的数据库操作Service
* @createDate 2025-05-02 02:37:23
*/
@Service
public class CourseService {

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CheckMapper checkMapper;
    @Autowired
    private ClassesMapper classesMapper;

    public List<Course> list() {

        return courseMapper.selectList(null);
    }

    public Page<Course> page(CourseParam courseParam) {

        return courseMapper.selectPage(courseParam, new LambdaQueryWrapper<Course>()
                .eq(courseParam.getWeekDay() > 0, Course::getWeekDay, courseParam.getWeekDay())
                .eq(courseParam.getClassesId() > 0, Course::getClassesId, courseParam.getClassesId())
                .like(courseParam.getCourseName() != null, Course::getCourseName, courseParam.getCourseName())
                .eq(courseParam.getCheckType() > 0, Course::getCheckType, courseParam.getCheckType())
                .orderByAsc(Course::getStartTime)
        );
    }

    public List<CourseResponse> leaveList(CourseParam courseParam) {

        int loginId = Integer.parseInt(StpUtil.getLoginId().toString());
        courseParam.setUserId(loginId);

        // 查询用户信息，找到班级信息
        User user = userMapper.selectById(courseParam.getUserId());
        // 通过leaveDate获取星期几
        int weekDay = courseParam.getLeaveDate().getDayOfWeek().getValue();

        List<Course> courseList = courseMapper.selectList(new LambdaQueryWrapper<Course>()
                .eq(Course::getClassesId, user.getClassesId())
                .eq(Course::getWeekDay, weekDay)
        );

        // 查询每一个课程的签到状态
        List<CourseResponse> courseResponseList = courseList.stream().map(course -> {
            CourseResponse courseResponse = new CourseResponse();
            Check check = checkMapper.selectOne(new LambdaQueryWrapper<Check>()
                    .eq(Check::getCourseId, course.getId())
                    .eq(Check::getUserId, loginId)
                    .eq(Check::getCheckDate, courseParam.getLeaveDate())
            );

            BeanUtils.copyProperties(course, courseResponse);
            if (check == null) {
                courseResponse.setCheckStatus(CheckStatus.INIT.getCode());
            } else {
                courseResponse.setCheckStatus(check.getCheckStatus());
            }

            return courseResponse;
        }).toList();

        return courseResponseList;
    }

    public CourseResponse pullCourse() {

        // 通过用户id，时间来判断进行哪一个课程的签到
        // 查询当前的考勤设置
        LocalDate now = LocalDate.now();
        String hourAndMinute = String.format("%02d", LocalDateTime.now().getHour()) + ":" + String.format("%02d", LocalDateTime.now().getMinute());

        // 查询用户信息，找到班级信息
        int loginId = Integer.parseInt(StpUtil.getLoginId().toString());
        User user = userMapper.selectById(loginId);
        // 通过leaveDate获取星期几
        int weekDay = now.getDayOfWeek().getValue();

        // 查询今天所有的课程信息
        List<Course> courseList = courseMapper.selectList(Wrappers.<Course>lambdaQuery()
                .eq(Course::getClassesId, user.getClassesId())
                .eq(Course::getWeekDay, weekDay)
                .orderByAsc(Course::getStartTime)
        );

        CourseResponse localCourse = null;
        for (Course course : courseList) {

            CourseResponse courseResponse = new CourseResponse();
            BeanUtils.copyProperties(course, courseResponse);

            // 查询是否有进行考勤打卡
            Check check = checkMapper.selectOne(Wrappers.<Check>lambdaQuery()
                    .eq(Check::getCourseId, course.getId())
                    .apply("DATE(check_date) = {0}", now)
                    .eq(Check::getUserId, loginId)
            );

            // 判断最近的打卡时间
            if (course.getStartTime().compareTo(hourAndMinute) <= 0 && course.getEndTime().compareTo(hourAndMinute) >= 0) {
                if (check != null) {
                    // 代表已经签到
                    courseResponse.setCheckStatus(check.getCheckStatus());
                } else {
                    // 代表未签到
                    courseResponse.setCheckStatus(CheckStatus.INIT.getCode());
                }
                localCourse = courseResponse;
                break;
            } if (course.getStartTime().compareTo(hourAndMinute) >= 0) {
                if (check != null) {
                    // 代表已经签到
                    courseResponse.setCheckStatus(check.getCheckStatus());
                    localCourse = courseResponse;
                    break;
                }
            } else {
                // 代表迟到，默认5分钟
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
                String plusTime = LocalTime.parse(course.getStartTime(), formatter).plus(Duration.ofMinutes(5)).format(formatter);

                if (check == null) {
                    if (plusTime.compareTo(hourAndMinute) >= 0) {
                        // 5分钟内刚迟到
                        // 代表已经签到
                        courseResponse.setCheckStatus(CheckStatus.LATE.getCode());
                        localCourse = courseResponse;
                        break;
                    }
                }
            }

        }

        return localCourse;

    }

    public Course selectOne(Course course) {

        return courseMapper.selectOne(new LambdaQueryWrapper<Course>()
                .eq(Course::getId, course.getId())
        );
    }

    public void update(Course course) {

        courseMapper.update(null, new LambdaUpdateWrapper<Course>()
                .eq(Course::getId, course.getId())
                .set(Course::getCourseName, course.getCourseName())
                .set(Course::getClassesId, course.getClassesId())
                .set(Course::getWeekDay, course.getWeekDay())
                .set(Course::getStartTime, course.getStartTime())
                .set(Course::getEndTime, course.getEndTime())
                .set(Course::getCheckType, course.getCheckType())
                .set(Course::getLat, course.getLat())
                .set(Course::getLon, course.getLon())
                .set(Course::getCheckContent, course.getCheckContent())
        );
    }

    public void create(Course course) {

        courseMapper.insert(course);
    }

    public void updateLocation(Course course) {

        courseMapper.update(null, new LambdaUpdateWrapper<Course>()
               .eq(Course::getId, course.getId())
               .set(Course::getLat, course.getLat())
               .set(Course::getLon, course.getLon())
        );
    }
}
